package com.systop.asset.controller;

import com.github.pagehelper.PageInfo;
import com.google.zxing.WriterException;
import com.systop.asset.entity.Asset;
import com.systop.asset.entity.AssetCategories;
import com.systop.asset.entity.RestResponse;
import com.systop.asset.entity.vo.AssetVo;
import com.systop.asset.service.IAssetService;
import com.systop.asset.utils.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.List;

/**
 * <p>ClassName : AssetController</p>
 * <p>Description : </p>
 *
 * @author 孙伟光
 * @version 1.0
 * @date 2025/6/26 15:40
 */
@RestController
@RequestMapping("/system/asset")
public class AssetController {

    @Autowired
    private IAssetService  assetService;

    @GetMapping({"/page"})
    public RestResponse<PageInfo<AssetVo>> page(Asset asset) {
        try {
            // 启动分页
            PageUtils.startPage();
            // 调用服务层方法获取资产列表(会自动分页)
            List<AssetVo> list = assetService.getAssetList(asset);
            // 将查询结果包装成PageInfo对象返回
            return RestResponse.success(new PageInfo<>(list));
        } finally {
            // 确保清除分页线程变量
            PageUtils.clearPage();
        }
    }

    /**
     * 根据资产ID获取资产详情
     * @param id 资产ID，不能为null
     * @return 包含资产详情的响应对象，若id为空返回错误响应(500)，若资产不存在返回错误响应(500)
     * @throws IllegalArgumentException 如果传入的id参数为null
     */
    @GetMapping({"/{id}"})
    public RestResponse<AssetVo> getAssetById(@PathVariable("id") Long id){
        // 参数校验：检查资产ID是否为空
        if (id == null) {
            return RestResponse.failure(500, "资产编号不能为空");
        }

        // 调用服务层获取资产信息
        AssetVo assetVo = assetService.getAssetVoById(id);

        // 检查资产是否存在
        if (assetVo == null) {
            return RestResponse.failure(500, "资产不存在");
        }

        // 返回成功响应及资产数据
        return RestResponse.success(assetVo);
    }

    /**
     * 根据查询条件获取资产列表
     * <p>通过传入的资产查询条件对象，获取符合条件的资产列表</p>
     *
     * @param asset 资产查询条件对象，包含各种查询条件参数。可以为null，表示查询所有资产
     * @return 包含资产列表的响应对象，其中data字段为查询到的资产列表(List<Asset>)
     *         即使没有查询到数据也会返回成功响应，data字段为空列表
     */
    @GetMapping("/list")
    public RestResponse<List<AssetVo>> list(Asset asset)
    {
        // 调用服务层方法，根据查询条件获取资产列表
        List<AssetVo> list = assetService.getAssetList(asset);

        // 将查询结果包装成成功响应返回
        return RestResponse.success(list);
    }

    /**
     * 添加单个资产
     * <p>接收资产信息对象并保存到数据库</p>
     *
     * @param asset 资产信息对象，包含资产的各种属性信息。不能为null
     * @return 包含操作结果的响应对象，成功时返回成功消息，失败时返回错误消息和状态码(500)
     *         可能的返回情况：
     *         1. 参数校验失败：返回错误响应(500)和"资产信息不能为空"
     *         2. 保存成功：返回成功响应和"资产添加成功"
     *         3. 保存失败：返回错误响应(500)和"资产添加失败"
     *         4. 发生异常：返回错误响应(500)和异常信息
     */
    @PostMapping
    public RestResponse add(@RequestBody Asset asset){
        // 参数校验：检查传入的资产对象是否为空
        if (asset == null) {
            return RestResponse.failure(500, "资产信息不能为空");
        }

        try {
            // 调用服务层方法添加资产，返回影响的行数
            int result = assetService.addAsset(asset);

            // 根据服务层返回结果判断操作是否成功
            if (result > 0) {
                return RestResponse.success("资产添加成功");
            } else {
                return RestResponse.failure(500, "资产添加失败");
            }
        } catch (Exception e) {
            // 捕获并处理添加资产过程中可能出现的异常
            return RestResponse.failure(500, "资产添加异常: " + e.getMessage());
        }
    }

    /**
     * 批量添加资产
     * <p>根据提供的资产模板和数量，批量创建相同类型的资产</p>
     *
     * @param asset 资产模板对象，包含要批量创建的资产的基本属性信息。不能为null
     * @param count 要创建的资产数量，必须大于0
     * @return 包含操作结果的响应对象，可能返回以下情况：
     *         1. 参数校验失败：返回错误响应(500)和"资产信息不能为空"
     *         2. 批量创建成功：返回成功响应和"资产批量添加成功"
     *         3. 批量创建失败：返回错误响应(500)和"资产批量添加失败"
     *         4. 发生异常：返回错误响应(500)和异常信息
     */
    @PostMapping("/batch/{count}")
    public RestResponse addAssetBatch(@PathVariable("count") int count, @RequestBody Asset asset){
        // 参数校验：检查传入的资产模板对象是否为空
        if (asset == null) {
            return RestResponse.failure(500, "资产信息不能为空");
        }
        if (count < 1) {
            return RestResponse.failure(500, "数量必须大于0");
        }
        try {
            // 调用服务层方法批量添加资产，返回实际创建的资产数量
            int result = assetService.addAssetBatch(asset, count);

            // 根据服务层返回结果判断操作是否成功
            if (result > 0) {
                return RestResponse.success("资产批量添加成功");
            } else {
                return RestResponse.failure(500, "资产批量添加失败");
            }
        } catch (Exception e) {
            // 捕获并处理批量添加过程中可能出现的异常
            return RestResponse.failure(500, "资产批量添加异常: " + e.getMessage());
        }
    }

    /**
     * 根据指定资产ID复制创建多个相同资产
     * <p>通过现有资产ID查询资产信息，然后批量复制创建指定数量的相同资产</p>
     *
     * @param id 要复制的资产ID，不能为null
     * @param count 要创建的资产数量，不能为null且必须大于0
     * @return 包含操作结果的响应对象，可能返回以下情况：
     *         1. 参数校验失败：返回错误响应(500)和相应错误信息
     *         2. 资产不存在：返回错误响应(500)和"编号错误，资产不存在"
     *         3. 复制成功：返回成功响应和"复制资产成功"
     *         4. 复制失败：返回错误响应(500)和"复制资产失败"
     *         5. 发生异常：返回错误响应(500)和异常信息
     */
    @PostMapping("/copy/{id}/{count}")
    public RestResponse copy(@PathVariable("id") Long id, @PathVariable("count") Integer count){
        // 参数校验：检查传入的参数是否为空
        if (id == null) {
            return RestResponse.failure(500, "编号不能为空");
        }
        if (count == null) {
            return RestResponse.failure(500, "数量不能为空");
        }
        if (count < 1) {
            return RestResponse.failure(500, "数量必须大于0");
        }

        try {
            //查询对象信息
            Asset asset = assetService.getAssetById(id);
            if (asset == null) {
                    return RestResponse.failure(500, "编号错误，资产不存在");
            }
            // 调用服务层方法批量添加资产，返回实际创建的资产数量
            int result = assetService.copy(asset, count);

            // 根据服务层返回结果判断操作是否成功
            if (result > 0) {
                return RestResponse.success("复制资产成功");
            } else {
                return RestResponse.failure(500, "复制资产失败");
            }
        } catch (Exception e) {
            // 捕获并处理批量添加过程中可能出现的异常
            return RestResponse.failure(500, "复制资产异常: " + e.getMessage());
        }
    }

    /**
     * 更新资产信息
     * <p>根据提供的资产对象更新数据库中对应的资产记录</p>
     *
     * @param asset 要更新的资产对象，包含资产ID和需要更新的字段信息。不能为null
     * @return 包含操作结果的响应对象，可能返回以下情况：
     *         1. 参数校验失败：返回错误响应(500)和"资产信息不能为空"
     *         2. 更新成功：返回成功响应和"资产更改成功"
     *         3. 更新失败(未找到对应记录)：返回错误响应(500)和"资产更改失败"
     *         4. 发生异常：返回错误响应(500)和异常信息
     */
    @PutMapping
    public RestResponse update(@RequestBody Asset asset){
        // 参数校验：检查传入的资产模板对象是否为空
        if (asset == null) {
            return RestResponse.failure(500, "资产信息不能为空");
        }

        try {
            // 调用服务层方法修改资产，返回实际修改的资产数量
            int result = assetService.updateAsset(asset);

            // 根据服务层返回结果判断操作是否成功
            if (result > 0) {
                return RestResponse.success("资产更改成功");
            } else {
                return RestResponse.failure(500, "资产更改失败");
            }
        } catch (Exception e) {
            // 捕获并处理修改过程中可能出现的异常
            return RestResponse.failure(500, "资产更改异常: " + e.getMessage());
        }
    }

    /**
     * 删除指定ID的资产
     * <p>根据资产ID从数据库中删除对应的资产记录</p>
     *
     * @param id 要删除的资产ID，不能为null
     * @return 包含操作结果的响应对象，可能返回以下情况：
     *         1. 参数校验失败：返回错误响应(500)和"编号不能为空"
     *         2. 删除成功：返回成功响应和"资产删除成功"
     *         3. 删除失败(未找到对应记录)：返回错误响应(500)和"资产删除失败"
     *         4. 发生异常：返回错误响应(500)和异常信息
     */
    @DeleteMapping("/{id}")
    public RestResponse deleteAsset(@PathVariable("id") Long id){
        // 参数校验：检查传入的资产模板对象是否为空
        if (id == null) {
            return RestResponse.failure(500, "编号不能为空");
        }

        try {
            // 调用服务层方法删除资产，返回实际删除的资产数量
            int result = assetService.deleteAsset(id);

            // 根据服务层返回结果判断操作是否成功
            if (result > 0) {
                return RestResponse.success("资产删除成功");
            } else {
                return RestResponse.failure(500, "资产删除失败");
            }
        } catch (Exception e) {
            // 捕获并处理删除过程中可能出现的异常
            return RestResponse.failure(500, "资产删除异常: " + e.getMessage());
        }
    }
}
